from keystone.common import serializer
from keystone.common import wsgi
from keystone import config
from keystone import exception
from keystone.openstack.common import jsonutils
from keystone.common import logging
import pdb
import json
import re
import pymongo
from keystone.identity import controllers
import sys


##### vom_auth for the demo
##### 2/15/2013

CONF = config.CONF


class vom_auth(wsgi.Middleware):
    def connect_mongo(self,dbname,collname):
        try:
            mongo_conn = pymongo.Connection('ec2-54-234-85-121.compute-1.amazonaws.com',27017)
            db = mongo_conn['mvom']
            coll=db[collname]
            return coll;
        except:
            print 'Unable to connect to the pyVOMS db'
            sys.exit(-1)

    def process_request(self, request):
        vom_username = ""
        vom_password = ""
        body_dict = {}
        body = request.body
        headers = request.headers
        environ = request.environ
        #print "vom_auth cloud_name: ", CONF.cloud_name
        #print "body:", body
	#print "headers keys:", headers.keys()
	#print "environ:", environ

        #context = request.environ.get(CONTEXT_ENV, {})
        ## this user had already been approved
        if 'X-Auth-Token' in headers:
            return self.application

        try:
            body_dict = json.loads(body)
            vo_name = body_dict['auth']['tenantName']
            vo_username = body_dict['auth']['passwordCredentials']['username']
            vo_password = body_dict['auth']['passwordCredentials']['password']
        except:
            return self.application
        ##
        ## transform the vom_* to the key_*
        ##

	#print "vom_auth input: ", vo_name, vo_username, vo_password
        (role_name, role_password, vo_sites) = self.vom_lookup(vo_name,vo_username,vo_password);
	#print "vom_auth output: ", role_name, role_password
        if role_name == None or role_password == None:
                    return self.application 

        body_dict['auth']['passwordCredentials']['username'] = role_name
        body_dict['auth']['passwordCredentials']['password'] = role_password
        body_dict['auth']['vo_access'] = vo_sites
        #print "body_dict:", body_dict
        body = json.dumps(body_dict)
        request.body = body; 
        return self.application



    def vom_lookup(self, voname, username, password):
	#print "vom_lookup: ", voname, username, password
        if not voname.startswith( "VO." ):
            return (None,None,None)

        # If cloud_name is not set, then disallow VO logins since we'll have no way to 
        # know which cloud the user may want to access
        if not CONF.cloud_name:
            return (None,None,None)            

        ## check to see if this user is a member of this VO with the right password
        #results = collection.find({"user":username,"passwd":password,"vom":voname}); 
        collection = self.connect_mongo("pvom","vom_list")
        vo_member = collection.find({"vo_name":voname,"user":username}); 

        ## We are only implementing one role per VO member at this time.
        ## 0 results = user or VO did not match.
	## 1 result  = user is a VO member with correct password
	## >1 result = VOMS Admin screwed up!
        if vo_member.count() != 1:
	    return (None,None,None)
	vo_role = vo_member[0]['role']
	vo_pswd = vo_member[0]['role_pswd']

	## Get the list of sites participating in this VO
	collection = self.connect_mongo("pvom","site_list")
        site_list = collection.find({'vo_name':voname})

	## There must be at least one site participating in a VO
	if site_list.count() < 1:
	    return (None,None,None)

	vo_sites = []
	for site in site_list:
	    # The cloud_name used in /etc/keystone/keystone.conf must agree with the cloud_name
            # used to register users and participating sites in pyVOMs.
	    if  CONF.cloud_name != site['cloud_name']:
	    	vo_sites.append( {'cloud_name':site['cloud_name'], 'auth_url':site['auth_url']} )
            else:
	    	vo_sites.append( {'cloud_name':site['cloud_name'], 'auth_url':"selfcloud"} )

	return ( vo_role, vo_pswd, vo_sites )
